library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity link_controller_tb is
end link_controller_tb; 

architecture tb of link_controller_tb is
  
  component link_controller is

    port ( clk          		: in  std_logic;
           host_address 		: in  std_logic_vector(31 DownTo 0);
           pixel_value      : in  std_logic;
           data_in_n    		: in  std_logic;
           data_in_ne   		: in  std_logic;
           data_in_nw   		: in  std_logic;
           data_in_s    		: in  std_logic;
           data_in_se   		: in  std_logic;
           data_in_sw   		: in  std_logic;
           data_in_e    		: in  std_logic;
           data_in_w    		: in  std_logic;
           data_out_n   		: out std_logic;
           data_out_ne  		: out std_logic;
           data_out_nw  		: out std_logic;
           data_out_s   		: out std_logic;
           data_out_se  		: out std_logic;
           data_out_sw  		: out std_logic;
           data_out_e   		: out std_logic;
           data_out_w   		: out std_logic;
           links_complete   : out std_logic;
           controller_label : out std_logic_vector(31 DownTo 0)
         );
   
  end component;

  component link_physical is

    port ( link_a   : in  std_logic;
           link_b   : in  std_logic;
           or_out   : out std_logic
         );

  end component;

  -- Global Signals
  signal controller_clk 								: std_logic;

  signal in_n           								: std_logic;
  signal in_ne          								: std_logic;
  signal in_nw          								: std_logic;
  signal in_s           								: std_logic;
  signal in_se          								: std_logic;
  signal in_sw          								: std_logic;
  signal in_e           								: std_logic;
  signal in_w           								: std_logic;

  signal out_n          								: std_logic;
  signal out_ne         								: std_logic;
  signal out_nw         								: std_logic;
  signal out_s          								: std_logic;
  signal out_se         								: std_logic;
  signal out_sw         								: std_logic;
  signal out_e          								: std_logic;
  signal out_w          								: std_logic;      

  signal links_address  								: std_logic_vector(31 DownTo 0);
  signal link_controller_pixel    			: std_logic;

  signal link_controller_complete 			: std_logic;
  signal link_controller_final_label    : std_logic_vector(31 DownTo 0);

begin

  a_link_controller : link_controller port map ( controller_clk,
                                                 links_address,
                                                 link_controller_pixel,
                                                 in_n,
                                                 in_ne,
                                                 in_nw,
                                                 in_s,
                                                 in_se,
                                                 in_sw,
                                                 in_e,
                                                 in_w,
                                                 out_n,
                                                 out_ne,
                                                 out_nw,
                                                 out_s,
                                                 out_se,
                                                 out_sw,
                                                 out_e,
                                                 out_w,
                                                 link_controller_complete,
                                                 link_controller_final_label
                                               );

  n_link  : link_physical port map ( out_n  , out_n  , in_n  );
  ne_link : link_physical port map ( out_ne , out_ne , in_ne );
  nw_link : link_physical port map ( out_nw , out_nw , in_nw );
  s_link  : link_physical port map ( out_s  , out_s  , in_s  );
  se_link : link_physical port map ( out_se , out_se , in_se );
  sw_link : link_physical port map ( out_sw , out_sw , in_sw );
  e_link  : link_physical port map ( out_e  , out_e  , in_e  );
  w_link  : link_physical port map ( out_w  , out_w  , in_w  );
                                                 
  process

    variable out_loop : integer := 0;
    variable in_loop : integer;

    procedure clock_link is
    begin
      controller_clk <= '1';
      wait for 1 ns;
      controller_clk <= '0';
      wait for 1 ns;
    end clock_link;

    procedure print_final_label is
    begin

      report ("Printing BuildLabel:  " & std_logic'image(link_controller_final_label(31))
                                       & std_logic'image(link_controller_final_label(30))
                                       & std_logic'image(link_controller_final_label(29))
                                       & std_logic'image(link_controller_final_label(28))
                                       & std_logic'image(link_controller_final_label(27))
                                       & std_logic'image(link_controller_final_label(26))
                                       & std_logic'image(link_controller_final_label(25))
                                       & std_logic'image(link_controller_final_label(24))
                                       & std_logic'image(link_controller_final_label(23))
                                       & std_logic'image(link_controller_final_label(22))
                                       & std_logic'image(link_controller_final_label(21))
                                       & std_logic'image(link_controller_final_label(20))
                                       & std_logic'image(link_controller_final_label(19))
                                       & std_logic'image(link_controller_final_label(18))
                                       & std_logic'image(link_controller_final_label(17))
                                       & std_logic'image(link_controller_final_label(16))
                                       & std_logic'image(link_controller_final_label(15))
                                       & std_logic'image(link_controller_final_label(14))
                                       & std_logic'image(link_controller_final_label(13))
                                       & std_logic'image(link_controller_final_label(12))
                                       & std_logic'image(link_controller_final_label(11))
                                       & std_logic'image(link_controller_final_label(10))
                                       & std_logic'image(link_controller_final_label(9))
                                       & std_logic'image(link_controller_final_label(8))
                                       & std_logic'image(link_controller_final_label(7))
                                       & std_logic'image(link_controller_final_label(6))
                                       & std_logic'image(link_controller_final_label(5))
                                       & std_logic'image(link_controller_final_label(4))
                                       & std_logic'image(link_controller_final_label(3))
                                       & std_logic'image(link_controller_final_label(2))
                                       & std_logic'image(link_controller_final_label(1))
                                       & std_logic'image(link_controller_final_label(0)));

    end print_final_label;

  begin

    link_controller_pixel <= '1';
    wait for 100 ns;

    links_address <= "01001000100010001000100010001000";
    wait for 100 ns;

    clock_link;
    clock_link;
    clock_link;

    while link_controller_complete = '0' loop

      report ("****************Clocking Cycle: " & integer'image(out_loop));
      out_loop := out_loop + 1;

      clock_link;
      clock_link;

      -- link reset is read on this cycle

      clock_link;
      clock_link;
      clock_link;
      
      -- link data set on this clock cycle

      clock_link;
      clock_link;
      clock_link;

      clock_link;
      clock_link;

      clock_link;
      clock_link;
      clock_link;


    end loop;

    print_final_label;

    wait;

  end process;

end tb;
